/*
 * @Author: YuanSong 
 * @Date: 2021-12-16 19:55:51 
 * @Last Modified by: YuanSong
 * @Last Modified time: 2021-12-27 19:40:46
 */
/**
 * 参数：[socketOpen|socketClose|sendMessage|socketError] = func，[socket连接成功时触发|连接关闭|发送消息|连接错误]
 * timeout：连接超时时间
 * @type {module.webSocket}
 */

export default interface webSocket extends WebSocket{
    param:{
        socketUrl:string | URL,
        timeout?:number,
        socketOpen?:()=>void,
        socketClose?:(T:any)=>void,
        socketError?:(T:any)=>void,
        socketMessage?:(T:any)=>void,
    },
    reconnectCount:number,
    socket:WebSocket | null,
    taskRemindInterval:NodeJS.Timeout | null,
    isSuccess:boolean,
    sendMessage?:(T:any)=>void,
         
}

export default class webSocket {
    constructor(param:any){
        this.param = param;
        this.reconnectCount = 0;
        this.taskRemindInterval = null;
        this.isSuccess = true;
        this.socket = null;
    }
    connection = ()=>{
        let {socketUrl,timeout = 0} = this.param;
        //检测当前浏览器是什么浏览器来决定用什么socket
        if ('WebSocket' in window){
            console.log("WebSocket");
            this.socket = new WebSocket(socketUrl);
        }
        if (this.socket) {
            this.socket.onopen = this.onopen;
            this.socket.onmessage = this.onmessage;
            this.socket.onclose = this.onclose;
            this.socket.onerror = this.onerror;
            
        }
        
        //检测返回的状态码 如果socket.readyState不等于1则连接失败，关闭连接
        if (timeout){
            let time = setTimeout(()=>{
                if (this.socket && this.socket.readyState !==1){
                    this.socket.close();
                }
            },timeout);
        }

    };

    //连接成功触发
    onopen = ()=>{
        let {socketOpen} = this.param;
        this.isSuccess = false //连接成功将标识符改为false
        socketOpen && socketOpen();
    }

    //关闭连接时触发
    onclose = (e:any)=>{
        this.isSuccess = true;
        console.log('关闭socket收到的数据');
        let {socketClose} = this.param;
        socketClose && socketClose(e);
        // 根据后端返回的状态码做操作
        // 我的项目是当前页面打开两个或者以上，就把当前以打开的socket关闭
        // 否则就20秒重连一次，直到重连成功为止
        if (e.code=='1005'){
            this.socket?.close();
        }
        else {
            this.taskRemindInterval = setInterval(()=>{
                if (this.isSuccess){
                    this.connection();
                }
                else {
                    this.taskRemindInterval && clearInterval(this.taskRemindInterval)
                }
            },10000);
        }
    }
    //接收到消息触发
    onmessage = (e:any)=>{
        // console.log('接收到了消息：',e);
        let {socketMessage} = this.param;
        socketMessage && socketMessage(e);
    }

    //error
    onerror = (e:any)=>{
        //socket 连接报错触发
        let {socketError} = this.param;
        this.socket = null;
        socketError && socketError(e);
    }

    //sendMessage
    sendMessage? = (value:any) =>{
        //像后端发送数据
        if (this.socket){
            this.socket.send(JSON.stringify(value));
        }
    }
    //closeSocket
    closeSocket= ()=>{
        this.socket?.close();
    }
}